#include "mythread.h"
#include <QString>
#include <QDebug>
QMutex MyThread::_mtuex;
QWaitCondition MyThread::_cond;
QVector<QString>* MyThread::_queue;//创建线程的时候,进行初始化
MyThread::MyThread()
{
    _leader=nullptr;
    close = false;
}

void MyThread::setLeader(Widget *ptr)
{
    _leader=ptr;
    _dirfile.setWidget(ptr);
}

void MyThread::run()
{
    while(1){
        //取出将要扫描的文件名,这里的文件名，一定是符合文件要求的。
        _mtuex.lock();
        while(_queue->empty()) {
            //如果close为true，代表要关闭了
            _cond.wait(&_mtuex);
            if(close){
                qDebug()<<"线程回收";
                _mtuex.unlock();
                return ;
            }
        }
        //扫描之前的准备工作
        int row = scanningInitialization();
        _mtuex.unlock();
        //开始扫描,不同线程扫描的一定是不同的文件，所以文件并不是共享资源
        scanning();
        //扫描结束
        //1.从记录正在扫描文件夹的map中移除对应的键值对
        _leader->scanding_remove(_dirfile._name);
        //2.删除记录正在扫描文件夹模型对应的行
        _leader->modelRemoveData(_leader->getScandingmodel(),row);
        //3.添加键值到记录历史文件夹的map中
        _leader->scandedInsert(_dirfile._name,_dirfile._model);
        //4.向记录历史扫描文件夹的模型中添加数据
        row = _leader->modelAddData(_leader->getScannedmodel(),_dirfile._name);
    }

}

void MyThread::setQueue(QVector<QString> *queue)
{
    _queue = queue;
}

void MyThread::threadWakeOne()
{
    _cond.wakeOne();
}

void MyThread::threadWakeAll()
{
    _cond.wakeAll();
}


void MyThread::setStop()
{
    _stop = !_stop;
}

void MyThread::setRun()
{
    _stop = true;
}

int MyThread::scanningInitialization()
{
    _dirfile._name = _queue->front();
    _dirfile.setModel();
     //1.添加文件夹名称和指针的键值对
    _leader->mapInsert(_dirfile._name,this);
     //2.添加文件夹名称和模型的键值对
    _leader->scandingInsert(_dirfile._name,_dirfile._model);
     //3.向正在扫描模型中添加数据,并获取行号
    int row = _leader->modelAddData(_leader->getScandingmodel(),_dirfile._name);
     //4.对ui中的tableview设置模型
    _leader->getTableView()->setModel(_dirfile._model);
    _queue->pop_front();
    return row;
}
qint64 getFolderSize(const QString &folderPath) {
    QDir dir(folderPath);
    qint64 size = 0;

    // 遍历文件
    foreach (const QFileInfo &fileInfo, dir.entryInfoList(QDir::Files)) {
        size += fileInfo.size(); // 累加文件大小（字节）
    }

    // 递归遍历子目录（排除"."和".."）
    foreach (const QString &subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
        size += getFolderSize(folderPath + QDir::separator() + subDir);
    }

    return size;
}
void MyThread::modelAdd(QFileInfo& tmpfile){
    bool isTrue = tmpfile.isDir();
    QString str = isTrue ? "true" : "false";  // 结果："true
    int size =0;
    if(isTrue) size=getFolderSize(_dirfile._name);
    else size =tmpfile.size();
    _dirfile.addRowDatas(tmpfile.fileName(),size,str);
}

void MyThread::setClose()
{
    close = true;
}
void MyThread::scanning()
{
    //1.获取文件条目
    QDir target_dir(_dirfile._name);
    QFileInfoList dirlist = target_dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
    //2.开始扫描
    int totalnum = dirlist.size();
    for(int i=0;i<totalnum;i++){
        //3.扫描文件，将文件名称、大小、是否是文件夹 按行添加放置在一个模型中
        modelAdd(dirlist[i]);
        //这里如果暂停当前扫描，就需要阻塞当前进程
        while(_stop){
             QThread::msleep(1000);//如果当前线程被终止扫描,就让其进行休眠
        }
        //4.每次扫描完成，发送一次信号,更新进度条的数据
        emit _leader->upateData((i+1)/totalnum * 100);
    }
}
